#!/bin/bash
#########################################################################################
# (C) Copyright NetEnrich Inc., 2012, All Rights Reserved.                              #
# File Name                     : build.sh                                              #
# Purpose                       : To update the itop set up                             #
#                               :                                                       #
#                               :                                                       #
#                               :                                                       #
# Version                       : 1.0                                                   #
# Revision                      :                                                       #
# Original Author               : Ambuj Jain                                         #
# Date                          : Oct 22, 2012                                          #
# Modification details          :                                                       #
# Reviewed By                   :                                                       #
# Tested by                     :                                                       #
#########################################################################################

export LANG=C

# Check we're running as root
if [ "$(id -u)" != "0" ]; then
  echo "The update script must be run as root"
  exit 1
fi

BASEDIR=$(dirname $0)
cd $BASEDIR

if [ "$#" -ne 1 ] || ! [ "$1" == "db" -o "$1" == "itop" -o "$1" == "cn" ] 
then
  echo 
  echo "Please provide the server type to be updated. [db | itop | cn]"
  echo "Usage: $0 <cn|db|itop>"
  echo
  exit 1
fi

LOGFILE="$BASEDIR/install.log";

updateUFW () {
    if [ -f $1/ufw/before.rules ];
    then
	cp -f $1/ufw/before.rules /etc/ufw/before.rules
	R1=$?
	service ufw restart  >> $LOGFILE 2>&1
	R2=$?
	if [ $R1 -eq 0 -a $R2 -eq 0 ]; then
		echo "SUCCESS: Update firewall" >> $LOGFILE;
	else
		echo "FAILURE: Update firewall" >> $LOGFILE;
		return 1;
	fi
	return 0
    fi
}

add_nfs_mon_script(){

	#line="*/10 * * * * /opt/scripts/check_nfs_mount.sh >/dev/null 2>&1"
	cp -f scripts/check_nfs_mount.sh /opt/scripts/check_nfs_mount.sh
        chmod +x /opt/scripts/check_nfs_mount.sh
	
	#/usr/bin/crontab -u root -l | grep check_nfs_mount 
	#if [ $? -ne 0  ]; then
	#	(/usr/bin/crontab -u root -l; echo "$line" ) | /usr/bin/crontab -u root -
	#	echo "NFS monitoring script is added to cron"  >> $LOGFILE
	#	return $?
	#else
	#	echo "NFS monitoring script is already added to cron"  >> $LOGFILE
	#fi

	#/bin/mount -t nfs,nfs4|grep /opt/datastore >/dev/null 2>&1
	/bin/mount -t nfs,nfs4 | grep "^.* on ${MOUNTPATH} type nfs.*$" > /dev/null 2>&1
	if [ $? -eq 0 ]; then
		touch /opt/datastore/.nfs_stale_test
		chmod 666 /opt/datastore/.nfs_stale_test
	fi
	
	return 0
}

tcp_tuning(){

  
 cat <<EOF >> /etc/sysctl.conf
# not to start with default window size for existing TCP connections that have been idle for too long 
net.ipv4.tcp_slow_start_after_idle=0
# Set maximum network input buffer queue length
net.core.netdev_max_backlog = 10000
# Set maximum TCP window sizes
net.core.rmem_max = 12582912
net.core.wmem_max = 12582912
# Set minimum, default, and maximum TCP buffer limits
net.ipv4.tcp_rmem = 8192 87380 12582912
net.ipv4.tcp_wmem = 8192 87380 12582912
net.core.rmem_default=229376
net.core.wmem_default=229376
# don't touch tcp_mem for two reasons: Firstly, unlike tcp_rmem and tcp_wmem it's in pages, not bytes, so it's likely to confuse the hell out of you. Secondly, it's already auto-tuned very well by Linux based on the amount of RAM.
#net.ipv4.tcp_mem= 8388608 8388608 8388608
# congestion control (default cubic)
# /sbin/modprobe tcp_htcp
# sysctl net.ipv4.tcp_available_congestion_control
net.ipv4.tcp_congestion_control=htcp
# Disable caching of TCP congestion state (2.6 only). TCP will not cache metrics on closing connections.
net.ipv4.tcp_no_metrics_save = 1
# increase port range
net.ipv4.ip_local_port_range = 18000    65535
#enable window scaling
net.ipv4.tcp_window_scaling=1
# tcp selective acknowledgements. should be enabled (for wide area network communication), but it can increase CPU utilization.
net.ipv4.tcp_sack = 1
# disable ipv6
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
# enables calculation of RTT in a more accurate way (see RFC 1323) than the retransmission timeout; should be enabled for performance.
net.ipv4.tcp_timestamps = 1
# discourages the kernel from swapping idle processes to disk (default = 60)
vm.swappiness=10
# Disable source routing and redirects
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
net.ipv4.conf.default.accept_source_route = 0
# Log packets with impossible addresses for security
net.ipv4.conf.all.log_martians = 1 
# Make room for more TIME_WAIT sockets due to more clients,
# and allow them to be reused if we run out of sockets
# Also increase the max packet backlog
net.ipv4.tcp_max_syn_backlog = 10000
#net.ipv4.tcp_max_tw_buckets = 360000
# allow to reuse TIME_WAIT sockets for new connections
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 20
# enable fast recycling of TIME_WAIT sockets.. *** Don't use when working with NAT ***
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_syn_retries = 2
#maximum number of times a SYN/ACK segment for a passive TCP connection will be retransmitted
net.ipv4.tcp_synack_retries = 2
#maximum number of TCP keep-alive probes to send before giving up
net.ipv4.tcp_keepalive_probes = 3
#send out syncookies when the syn backlog queue of a socket overflows
net.ipv4.tcp_syncookies = 1
#number of attempts made to probe the other end of a connection which has been closed by our end
net.ipv4.tcp_orphan_retries = 1
# If your servers talk UDP, also up these limits
net.ipv4.udp_rmem_min = 8192
net.ipv4.udp_wmem_min = 8192
#controls TCP Packetization-Layer Path MTU discovery
net.ipv4.tcp_mtu_probing = 1
#net.ipv4.tcp_rfc1337 = 1
# if enabled, TCP performs receive buffer auto-tuning
net.ipv4.tcp_moderate_rcvbuf = 1
# enable TCP Forward Acknowledgement support
net.ipv4.tcp_fack = 1

EOF

  /sbin/sysctl -p /etc/sysctl.conf
}

update_reg() {
  if [ -f /opt/admin/bin/reg/reg.pl ];
  then
    #echo "Patching the reg.pl file..." | tee -a $LOGFILE
    #cp ncare/reg.pl /opt/admin/bin/reg/reg.pl
    #chown root.root /opt/admin/bin/reg/reg.pl
    #chmod 755 /opt/admin/bin/reg/reg.pl
    #echo "Patching the reg.pl file completed" | tee -a $LOGFILE
    
    echo "Re-registration of the Connection server..." | tee -a $LOGFILE
    /usr/bin/perl /opt/admin/bin/reg/reg.pl
    echo "Re-registration of the CSN is completed" | tee -a $LOGFILE
  fi
}

snmpd_change() {
  echo "SNMP change to monitor nfs mount" | tee -a $LOGFILE
  cp -f scripts/templates/snmpd.conf /opt/scripts/templates/snmpd.conf
  cp -f scripts/check_nfs_mount.sh /opt/scripts/
  chmod +x /opt/scripts/check_nfs_mount.sh
  
  grep nfs_status /etc/snmp/snmpd.conf
  if [ $? -ne 0  ]; then
    echo "exec nfs_status /opt/scripts/check_nfs_mount.sh" >> /etc/snmp/snmpd.conf
    echo "Restarting snmpd..." | tee -a $LOGFILE
    service snmpd restart
  else
    echo "NFS mount is already in hence doing nothing.." | tee -a $LOGFILE
  fi  
  
}

updateRepo() {
  echo "Updating OS packages..." | tee -a $LOGFILE
  mkdir /opt/rep
  tar -xvzf commons/debian_packages/dists.tar.gz -C /opt/rep/  >> $LOGFILE 2>&1
  tar -xvzf commons/debian_packages/pool.tar.gz -C /opt/rep/  >> $LOGFILE 2>&1
  echo "deb file:///opt/rep/ precise main" > /etc/apt/sources.list

  apt-get update >> $LOGFILE 2>&1
  echo "Updating kernel..." | tee -a $LOGFILE
  apt-get -y dist-upgrade >> $LOGFILE 2>&1
  echo "Removing unwanted packages that are not required anymore..." | tee -a $LOGFILE
  apt-get -y autoremove >> $LOGFILE 2>&1
  rm -fr /opt/rep/
}

update_ncare() {
  while true; do
    echo -n "Have you upgraded Database (y/n)>"
    read choice
    echo
    case $choice in
      [yY] | [yY][Ee][Ss])
        break
        ;;
      [nN] | [n|N][O|o] )
        echo "Not done, you can't proceed the installation";
        return 0
        ;;
      *)
        echo "That is not a valid choice, try again"
        ;;
    esac
  done
  
  echo "Starting upgrade process..." | tee -a $LOGFILE

  #updateRepo
  #updateUFW "ncare"

  ETH2_IP=`/sbin/ifconfig eth2 2>&1 | /bin/grep Bcast | /usr/bin/awk '{print $2}' | /usr/bin/awk -F: '{print $2}'`
  ETH3_IP=`/sbin/ifconfig eth3 2>&1 | /bin/grep Bcast | /usr/bin/awk '{print $2}' | /usr/bin/awk -F: '{print $2}'`
  if [ -f /etc/monit/conf.d/ncare.monitrc ];
  then
    if [ "$ETH2_IP" = "" -o "$ETH3_IP" = "" ]; then
      echo "Please configure eth2 and eth3 interfaces before update"
      return 0
    fi
  fi

  if [ -f /etc/monit/conf.d/searchengine.monitrc ];
  then
    echo "Stopping searchengine service..." | tee -a $LOGFILE
    monit stop searchengine  >> $LOGFILE 2>&1
    service searchengined stop >> $LOGFILE 2>&1
  fi
  
  if [ -f /etc/monit/conf.d/ncare.monitrc ];
  then
    echo "Stopping ncare service..." | tee -a $LOGFILE
    monit stop ncare  >> $LOGFILE 2>&1
    service ncare stop >> $LOGFILE 2>&1
  fi
  
  if [ -f /etc/monit/conf.d/rdp2swf.monitrc ];
  then
    echo "Stopping rdp2swf service..." | tee -a $LOGFILE
    monit stop rdp2swf >> $LOGFILE 2>&1
    service rdp2swfd stop >> $LOGFILE 2>&1
  fi

  sleep 8
  
  cp -f /opt/ncare/conf/ncare.xml .
  
  rm -rf /var/log/ncare/*  >> $LOGFILE 2>&1
  rm -fr /opt/ncare/*  >> $LOGFILE 2>&1
  
  echo "Updating the ncare application..." | tee -a $LOGFILE
  
  tar -xvzf ncare/ncare.tar.gz -C /  >> $LOGFILE 2>&1

  if [ -f /etc/monit/conf.d/ncare.monitrc ];
  then
    sed -e "s/@HTTP_IP@/$ETH2_IP/g" -e "s/@TLS_IP@/$ETH3_IP/g" /opt/ncare/conf/ncare.xml.tpl > /opt/ncare/conf/ncare.xml | tee -a $LOGFILE
  fi

  fromdos /etc/init.d/ncare >> $LOGFILE 2>&1
  fromdos /etc/init.d/searchengined >> $LOGFILE 2>&1
  fromdos /etc/init.d/rdp2swfd >> $LOGFILE 2>&1
  chown itop.itop /opt/ncare -R >> $LOGFILE 2>&1
  chmod 755 /etc/init.d/ncare /etc/init.d/searchengined /etc/init.d/rdp2swfd /opt/ncare/bin/ -R >> $LOGFILE 2>&1
  mkdir -p /var/log/ncare  >> $LOGFILE 2>&1
  chown itop.itop /var/log/ncare -R >> $LOGFILE 2>&1
  chmod 744 /var/log/ncare -R >> $LOGFILE 2>&1

  echo "Doing tcp tunnig and disabling ipv6..." | tee -a $LOGFILE
  tcp_tuning
  
  echo "Adding NFS monitoring script..." | tee -a $LOGFILE
  add_nfs_mon_script

  echo "Starting the services..." | tee -a $LOGFILE

  if [ -f /etc/monit/conf.d/searchengine.monitrc ];
  then
    echo "Starting service searchengine..." | tee -a $LOGFILE
    monit start searchengine
  fi
  
  if [ -f /etc/monit/conf.d/ncare.monitrc ];
  then
    echo "Starting service ncare..." | tee -a $LOGFILE
    monit start ncare
  fi
  
  if [ -f /etc/monit/conf.d/rdp2swf.monitrc ];
  then
    echo "Starting service rdp2swf..." | tee -a $LOGFILE
    monit start rdp2swf
  fi

  update_reg

  sleep 5

  snmpd_change
  
  echo "The node has been successfully updated..." | tee -a $LOGFILE
  return 0
}

update_db() {
  while true; do
    echo -n "Have you stopped services in all CN nodes (CS, RDP2SWF and SE) and itop (y/n)>"
    read choice
    echo
    case $choice in
      [yY] | [yY][Ee][Ss])
        break
        ;;
      [nN] | [n|N][O|o] )
        echo "Not done, you can't proceed the installation";
        return 0
        ;;
      *)
        echo "That is not a valid choice, try again"
        ;;
    esac
  done
  
  echo "Starting upgrade process..." | tee -a $LOGFILE

  #updateRepo
  #updateUFW "db"

  d=`date +%s`
  dump_dir=/var/lib/mysqldump/$d
  mkdir -p $dump_dir
    
  echo "Starting DB backup in directory $dump_dir ..." | tee -a $LOGFILE
  mysqldump -umsp -pmsp msp > $dump_dir/msp.sql --skip-lock-tables 2>&1
  mysqldump -umsp_report -pmsp_report msp_report > $dump_dir/msp_report.sql --skip-lock-tables 2>&1
  mysqldump -umsp_mon -pmsp_mon msp_mon > $dump_dir/msp_mon.sql --skip-lock-tables 2>&1 
 
  echo "Starting Database upgrade..." | tee -a $LOGFILE
  tar -xvzf db/itop-db.tar.gz -C / >> $LOGFILE 2>&1
  sh /opt/sql/upgrade.sh >> $LOGFILE 2>&1
  mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -pxAVa6Aze mysql
  rm /opt/sql/upgrade.sh /install.sh >> $LOGFILE 2>&1
  cp -f db/db_backup /opt/scripts/
  cp -f db/db_restore /opt/scripts/
  chmod 755 /opt/scripts/db_restore

  snmpd_change
  
  echo "Doing tcp tunnig and disabling ipv6..." | tee -a $LOGFILE
  tcp_tuning
  
  echo "The node has been successfully updated..." | tee -a $LOGFILE
  return 0
}

update_itop() {
  while true; do
    echo -n "Have you upgraded Database (y/n)>"
    read choice
    echo
    case $choice in
      [yY] | [yY][Ee][Ss])
        break
        ;;
      [nN] | [n|N][O|o] )
        echo "Not done, you can't proceed the installation";
        exit 0
        ;;
      *)
        echo "That is not a valid choice, try again"
        ;;
    esac
  done

  #echo "Installing 7zip" | tee -a $LOGFILE
  #dpkg -i itop/p7zip-full_9.20.1~dfsg.1-4_amd64.deb  >> $LOGFILE 2>&1

  #echo "Copying openssl signing bin file for agent" | tee -a $LOGFILE
  #cp -rf itop/osslsigncode /usr/local/bin/
  #chmod +x /usr/local/bin/osslsigncode
 
  echo "Starting upgrade process..." | tee -a $LOGFILE

  #updateRepo 
  #updateUFW "itop"

  echo "Stopping itop service..." | tee -a $LOGFILE
  monit stop itop >> $LOGFILE 2>&1
  service itop stop >> $LOGFILE 2>&1
  sleep 10
  
  echo "Updating the itop application..." | tee -a $LOGFILE
  
  rm -fr /opt/itop/webapps/* /opt/itop/work/* /var/log/itop/* >> $LOGFILE 2>&1
  
  echo "Clearing the memcache..." | tee -a $LOGFILE
  nc membase 11211 <<EOF
flush_all
quit
EOF
  
  echo "Updating the application war..." | tee -a $LOGFILE
  tar -xvzf itop/itop.tar.gz -C / >> $LOGFILE 2>&1
  chmod -R 755 /opt/itop  >> $LOGFILE 2>&1
  chown -R itop:itop /opt/itop  >> $LOGFILE 2>&1
  chmod -R 755 /etc/init.d/itop >> $LOGFILE 2>&1

  echo "Copying Linux NCare Agent packages..." | tee -a $LOGFILE
  tar -xvzf itop/linux-ncare-pkgs.tar.gz -C /opt/itop/ncare-agent/ >> $LOGFILE 2>&1
  chmod -R 755 /opt/itop/ncare-agent/  >> $LOGFILE 2>&1
  chown -R itop:itop /opt/itop/ncare-agent/  >> $LOGFILE 2>&1

  echo "Copying WebHelp files..." | tee -a $LOGFILE
  tar -xvzf itop/WebHelp.tar.gz -C /opt/itop/webapps/ >> $LOGFILE 2>&1
  chmod -R 755 /opt/itop/webapps/WebHelp  >> $LOGFILE 2>&1
  chown -R itop:itop /opt/itop/webapps/WebHelp  >> $LOGFILE 2>&1

  echo "Doing tcp tunnig and disabling ipv6..." | tee -a $LOGFILE
  tcp_tuning
  
  echo "Adding NFS monitoring script..." | tee -a $LOGFILE
  add_nfs_mon_script
  
  echo "Restarting the services" | tee -a $LOGFILE
  monit start itop  >> $LOGFILE 2>&1
  sleep 5

  snmpd_change

  echo "The node has been successfully updated...reboot the server now" | tee -a $LOGFILE
  return 0
}

stop_services(){
  if [ -f /etc/monit/conf.d/searchengine.monitrc ];
  then
    echo "Stopping service searchengine..."
    monit stop searchengine
    service searchengined stop
  fi
  
  if [ -f /etc/monit/conf.d/ncare.monitrc ];
  then
    echo "Stopping service ncare..."
    monit stop ncare
    service ncare stop
  fi
  
  if [ -f /etc/monit/conf.d/rdp2swf.monitrc ];
  then
    echo "Stopping service rdp2swf..."
    monit stop rdp2swf
    service rdp2swfd stop
  fi
  
  if [ -f /etc/monit/conf.d/itop.monitrc ];
  then
    echo "Stopping service itop..."
    monit stop itop
    service itop stop
  fi
}


valid_options(){
  while true; do
    echo ""
    echo "1. Just to stop required services before Database upgrade"
    echo "2. To upgrade the node"
    echo "0. Exit"
    echo
    
    echo -n "Enter your choice, or 0 for exit: "
    read choice
    echo
    case $choice in
      1)
        stop_services
        exit 0
        ;;
      2)
        break
        ;;
      0)
        echo "OK, see you later!"
        exit 0
        ;;
      *)
        echo "That is not a valid choice, try a number from 0 to 2."
        ;;
    esac  
  done
}


case "$1" in
  cn)
    if ! [ -f /etc/monit/conf.d/searchengine.monitrc -o -f /etc/monit/conf.d/rdp2swf.monitrc -o  -f /etc/monit/conf.d/ncare.monitrc ]
    then
      echo "It seems you run the script on this node with wrong server type.. so aborting.."
      exit 1
    fi
    valid_options
    update_ncare
    ;;
   
  db)
    valid_options
    update_db
    ;;
    
  itop)
    if ! [ -f /etc/monit/conf.d/itop.monitrc ]
    then
      echo "It seems you run the script on this node with wrong server type.. so aborting.."
      exit 1
    fi
    valid_options
    update_itop
    ;;
  *)
    echo "Usage: $0 {cn|db|itop}"
    exit 1
    ;;
esac

exit $?



